package com.quan.common.wx.utils.pay;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.n3r.idworker.Sid;

import com.quan.base.common.utils.IpHelper;
import com.quan.base.common.utils.XmlUtils;

/**
 * 微信支付订单辅助类
 * @author yhaoquan
 *
 */
public class PayOrderUtils {

	/**
	 * 订单对象，接收如下参数，Request对象中需含有如下参数
	 * 
	 * @param body
	 *            商品描述
	 * @param detail
	 *            商品详情
	 * @param total_fee
	 *            金额需要扩大100倍:1代表支付时是0.01
	 * @param trade_type
	 *            交易类型（JSAPI 公众号支付，NATIVE 扫码支付，APP APP支付）
	 * @param openid
	 *            用户标识，trade_type=JSAPI时（即公众号支付），此参数必传，此参数为微信用户在商户对应appid下的唯一标识
	 * @return UnifiedOrderRequest 统一下单对象
	 */
	public static UnifiedOrderRequest generatorOrder(HttpServletRequest request) {
		String body = request.getParameter("body");
		String detail = request.getParameter("detail");
		String total_fee = request.getParameter("total_fee");
		String trade_type = request.getParameter("trade_type");
		String openid = request.getParameter("openid");
		String ipAddr = IpHelper.getIpAddr(request);

		return generatorPayOrder(body, detail, total_fee, trade_type, openid, ipAddr);
	}

	/**
	 * 订单对象
	 * 
	 * @param body
	 *            商品描述
	 * @param detail
	 *            商品详情
	 * @param total_fee
	 *            标价金额，金额需要扩大100倍:1代表支付时是0.01
	 * @param trade_type
	 *            交易类型（JSAPI 公众号支付，NATIVE 扫码支付，APP APP支付）
	 * @param openid
	 *            用户标识，trade_type=JSAPI时（即公众号支付），此参数必传，此参数为微信用户在商户对应appid下的唯一标识
	 * @param ipAddr
	 *            客户端IP地址
	 * @return
	 */
	public static UnifiedOrderRequest generatorPayOrder(String body, String detail, String total_fee, String trade_type, String openid, String ipAddr) {
		try {
			// 随机字符串
			String noncestr = Sid.nextShort();
			// 商户订单号
			String orderId = Sid.next();
	
			UnifiedOrderRequest order = new UnifiedOrderRequest();
			order.setAppid(WXPayConfig.APPID);// 公众账号ID
			order.setMch_id(WXPayConfig.MCH_ID);// 商户号
			order.setNonce_str(noncestr);// 随机字符串
			order.setNotify_url(WXPayConfig.PAY_NOTIFY_URL);// 通知地址
			order.setSpbill_create_ip(ipAddr);// 终端IP
			order.setOut_trade_no(orderId);// 商户订单号
			order.setBody(body);// 商品描述
			order.setDetail(detail);// 详情
			order.setTotal_fee(total_fee); // 金额需要扩大100倍:1代表支付时是0.01
			order.setTrade_type(trade_type);// 交易类型（JSAPI 公众号支付，NATIVE 扫码支付，APP APP支付）
			order.setOpenid(openid);// 微信用户的openid
	
			SortedMap<String, String> packageParams = new TreeMap<String, String>();
			packageParams.put("appid", order.getAppid());
			packageParams.put("body", order.getBody());
			packageParams.put("detail", order.getDetail());
			packageParams.put("mch_id", order.getMch_id());
			packageParams.put("nonce_str", order.getNonce_str());
			packageParams.put("notify_url", order.getNotify_url());
			packageParams.put("openid", order.getOpenid());
			packageParams.put("out_trade_no", order.getOut_trade_no());
			packageParams.put("spbill_create_ip", order.getSpbill_create_ip());
			packageParams.put("total_fee", order.getTotal_fee());
			packageParams.put("trade_type", order.getTrade_type());
			
			//签名
			order.setSign(WXPayUtil.generateSignature(packageParams, WXPayConfig.APPKEY));
			
			return order;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null ;
	}
	
	public static RefundOrderRequest refundOrder() {
		
		
		return null ;
	}
	
	public static String RefundToXml(RefundOrderRequest refun) {
		return XmlUtils.beanToXml(refun).replace("__", "_");
	}
	
	/**
	 * 将订单对象转换为XML字符串
	 * @param order
	 * @return
	 */
	public static String OrderToXml(UnifiedOrderRequest order) {
		return XmlUtils.beanToXml(order).replace("__", "_");
	}
	
	/**
	 * 将统一下单请求返回的XML结果转换为UnifiedOrderRespose对象
	 * @param unifiedOrderResponseXml
	 * @return
	 */
	public static UnifiedOrderResponse XmlToOrderResponse(String unifiedOrderResponseXml) {
		return (UnifiedOrderResponse) XmlUtils.xmlToBean(unifiedOrderResponseXml, UnifiedOrderResponse.class, "xml") ;
	}
	
	/**
	 * 微信内H5调起支付的paySign签名
	 * @param noncestr 	随机字符串，不长于32位（从订单对象中获取）
	 * @param timestamp 时间戳，当前的时间
	 * @param prepay_id 统一下单接口返回的prepay_id参数值
	 * @return
	 */
	public static String getPaySign(String nonceStr, String timeStamp, String prepay_id) {
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appId", WXPayConfig.APPID);
		packageParams.put("signType", "MD5");
		packageParams.put("nonceStr", nonceStr);
		packageParams.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp()));
		packageParams.put("package", "prepay_id=" + prepay_id);
		String sign = null;// 这个梗，就是开头说的，弄了半天才弄出来的
		try {
			sign = WXPayUtil.generateSignature(packageParams, WXPayConfig.APPKEY);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sign ;
	}
	
	/**
	 * 微信内H5调起支付所需参数
	 * @param orderRequest 订单对象，使用参数（nonceStr）
	 * @param orderResponse 统一下单返回的预支付交易单信息，使用参数（prepay_id）
	 * @return Map集合
	 */
	public static Map<String, Object> getBrandWCPayRequest(UnifiedOrderRequest orderRequest, UnifiedOrderResponse orderResponse) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("appId", WXPayConfig.APPID);
		map.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp()));
		map.put("nonceStr", orderRequest.getNonce_str());
		map.put("package", "prepay_id=" + orderResponse.getPrepay_id());
		map.put("signType", "MD5");
		map.put("paySign", getPaySign(orderRequest.getNonce_str(), String.valueOf(WXPayUtil.getCurrentTimestamp()), orderResponse.getPrepay_id()));
		map.put("order", orderRequest);
		
		return map ;
	}
	
	/**
	 * 微信内H5调起支付所需参数
	 * @param timeStamp 时间戳，当前的时间
	 * @param nonceStr 	随机字符串，不长于32位（从订单对象中获取）
	 * @param prepay_id 统一下单接口返回的prepay_id参数值
	 * @param paySign	签名（通过getPaySign方法取得）
	 * @return Map集合
	 */
	public static Map<String, String> getBrandWCPayRequest(String timeStamp, String nonceStr, String prepay_id, String paySign) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("appId", WXPayConfig.APPID);
		map.put("timeStamp", timeStamp);
		map.put("nonceStr", nonceStr);
		map.put("package", "prepay_id=" + prepay_id);
		map.put("signType", "MD5");
		map.put("paySign", getPaySign(nonceStr, timeStamp, prepay_id));
		
		return map ;
	}
	
	/**
	 * 微信支付异步通知结果
	 * @param request
	 * @return XML字符串
	 */
	public static String getPayNotityResultXml(HttpServletRequest request){
		try {
			InputStream inputStream = request.getInputStream();
	        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
	        final StringBuffer stringBuffer = new StringBuffer();
	        String line = null;
	        while ((line = bufferedReader.readLine()) != null) {
	            stringBuffer.append(line);
	        }
	        String resultXml = stringBuffer.toString();
	        if (stringBuffer!=null) {
	            try {
	                bufferedReader.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        if (inputStream!=null) {
	            try {
	                inputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        return resultXml ;
		} catch (IOException e) {
			e.printStackTrace();
		}  
		
		return null;
	}
	
	/**
	 * 微信支付异步通知结果（将返回结果的XML转换为对象）
	 * @param payNotifyResultXml
	 * @return PayNotityResult
	 */
	public static PayNotityResult getPayNotityResult(String payNotifyResultXml){
		return (PayNotityResult) XmlUtils.xmlToBean(payNotifyResultXml, PayNotityResult.class, "xml") ;
	}

}
